// Copyright 2023 Huawei Cloud Computing Technology Co., Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef VMISOCKET_H
#define VMISOCKET_H

#include <memory>
#include <mutex>
//#include "Statistics/Statistics.h"
#include "MemoryManagement/VmiBuffer.h"

enum VmiSocketStatus {
    SOCKET_STATUS_INIT = 0, // 初始态
    SOCKET_STATUS_RUNNING = 1, // 运行态
    SOCKET_STATUS_EXIT = -1, // 退出态
    SOCKET_STATUS_DISCONN = -2, // socket连接断开
};

enum VmiSocketErrorCode {
    SOCKET_RECV_FAIL_RETRY = -1,   // 接收函数返回失败，可再调接收函数重试
    SOCKET_RECV_FAIL_DISCONN = -2, // 接收函数返回失败，SOCKET断链，不可用
    SOCKET_SEND_FAIL_RETRY = -3,   // 发送函数返回失败，可再调发送函数重试
    SOCKET_SEND_FAIL_DISCONN = -4, // 发送函数返回失败，SOCKET断链，不可用
};

enum VmiSocketOptionBitset {
    SOCKET_OPTION_BITSET_NODELAY = 0x1, // 对应TCP选项TCP_NODELAY
    SOCKET_OPTION_BITSET_QUICKACK = 0x2, // 对应TCP选项TCP_QUICKACK
};

enum VmiSocketReturnCode {
    SOCK_RET_SUCCESS = 0,
    SOCK_RET_FAILED = -1,
};

struct VmiSocketAddressGroup {
    unsigned int m_remoteIp = 0;
    unsigned short int m_remotePort = 0;
    unsigned int m_localIp = 0;
    unsigned short int m_localPort = 0;

    /**
     * @功能描述：构造函数
     */
    VmiSocketAddressGroup() : m_remoteIp(0), m_remotePort(0), m_localIp(0), m_localPort(0)
    {}

    /**
     * @功能描述：带参构造函数
     * @参数 [in] remoteIp：对端Ip
     * @参数 [in] remotePort：对端端口
     * @参数 [in] localIp：本地IP
     * @参数 [in] localIp：本地端口
     */
    VmiSocketAddressGroup(unsigned int remoteIp, unsigned short int remotePort, unsigned int localIp,
        unsigned short int localPort)
        : m_remoteIp(remoteIp), m_remotePort(remotePort), m_localIp(localIp), m_localPort(localPort)
    {}
};

class VmiEventNotice;

class VmiSocket : public std::enable_shared_from_this<VmiSocket> {
public:
    /**
     * @功能描述：默认构造函数
     */
    VmiSocket();

    /**
     * @功能描述：带参构造函数
     * @参数 [in] fd：套接字句柄
     * @参数 [in] address：IP地址、端口
     * @参数 [in] socketOption：套接字选项
     */
    VmiSocket(int fd, const VmiSocketAddressGroup &address, unsigned int socketOption);

    /*
     * @功能描述：虚析构函数
     */
    virtual ~VmiSocket() = default;

    /*
     * @功能描述：发送数据
     * @参数 [in] sendBuf：待发送数据buffer
     * @返回值：大于等于0表示实际发送的字节数，小于0表示失败
     */
    virtual ssize_t Send(const VmiBuffer &sendBuf) = 0;

    /*
     * @功能描述：接收数据
     * @参数 [in] recvBuf：接收buffer
     * @返回值：大于等于0表示实际接收到的字节数，小于0表示失败
     */
    virtual ssize_t Recv(const VmiBuffer &recvBuf) = 0;

    /*
     * @功能描述：通知socket断开
     */
    virtual void EventNotice();

    /*
     * @功能描述：注册socket断开通知
     * @参数 [in] eventNotice：处理断开的VmiEventNotice对象智能指针
     */
    virtual void SetEventNotice(std::shared_ptr<VmiEventNotice> eventNotice);

    /*
     * @功能描述：设置socket句柄
     * @参数 [in] fd：socket句柄
     */
    void SetFd(int fd);

    /*
     * @功能描述：获取socket句柄
     * @返回值：socket句柄
     */
    int GetFd();

    /*
     * @功能描述：设置状态
     * @参数 [in] status：状态，参见VmiSocketStatus定义
     */
    void SetStatus(int status);

    /*
     * @功能描述：获取状态
     * @返回值：状态，参见VmiSocketStatus定义
     */
    int GetStatus();

    /*
     * @功能描述：设置socket选项
     * @参数 [in] option：选项组合，参见VmiSocketOptionBitset定义
     */
    void SetSocketOption(unsigned int option);

    /*
     * @功能描述：获取当前的socket选项设置
     * @返回值：选项组合，参见VmiSocketOptionBitset定义
     */
    unsigned int GetSocketOption() const;

    /*
     * @功能描述：设置对端和本地的IP、端口地址
     * @参数 [in] remoteIp：联网的对端的IP
     * @参数 [in] remotePort：联网的对端的端口
     * @参数 [in] localIp：本地的IP
     * @参数 [in] localPort：本地的端口
     */
    void SetAddress(unsigned int remoteIp, unsigned short int remotePort, unsigned int localIp,
        unsigned short int localPort);

    /*
     * @功能描述：获取对端和本地的IP、端口地址
     * @参数 [out] remoteIp：用来返回对端的IP
     * @参数 [out] remotePort：用来返回对端的端口
     * @参数 [out] localIp：用来返回本地的IP
     * @参数 [out] localPort：用来返回本地的端口
     */
    void GetAddress(unsigned int &remoteIp, unsigned short int &remotePort, unsigned int &localIp,
        unsigned short int &localPort);

    /*
     * @功能描述：关闭socket抽象方法
     */
    virtual void CloseSocket() = 0;

    /*
     * @功能描述：连接服务端
     * @返回值：返回0成功，不等于0失败
     */
    virtual int Connect() = 0;

    /*
     * @功能描述：设置发送超时时间
     * @参数 [in] sec：秒
     * @参数 [in] usec：微秒
     */
    virtual void SetSendTimeout(long sec, long usec) = 0;

    /*
     * @功能描述：设置接收超时时间
     * @参数 [in] sec：秒
     * @参数 [in] usec：微秒
     */
    virtual void SetRecvTimeout(long sec, long usec) = 0;

    static const int INVALID_FD = -1;

protected:
    int m_fd = -1;
    int m_status = 0;
    unsigned int m_remoteIp = 0;
    unsigned short int m_remotePort = 0;
    unsigned int m_localIp = 0;
    unsigned short int m_localPort = 0;
    unsigned int m_socketOption = 0;
    std::shared_ptr<VmiEventNotice> m_eventNotice = nullptr;
    std::mutex m_socketMutex = {};
};

class VmiEventNotice {
public:
    /*
     * @功能描述：构造函数
     */
    VmiEventNotice() = default;

    /*
     * @功能描述：虚析构函数
     */
    virtual ~VmiEventNotice() = default;

    /*
     * @功能描述：通知socket断开
     * @参数 [in] socket：断开连接的VmiSocket智能指针
     */
    virtual void Notice(std::shared_ptr<VmiSocket> socket) = 0;
};

class VmiServerService {
public:
    /*
     * @功能描述：构造函数
     */
    VmiServerService() = default;

    /*
     * @功能描述：虚析构函数
     */
    virtual ~VmiServerService() = default;

    /*
     * @功能描述：通知新连接接入
     * @参数 [in] socket：新连接VmiSocket智能指针
     */
    virtual void Callback(std::shared_ptr<VmiSocket> socket) = 0;
};

#endif // VMISOCKET_H
